<template>
  <div class="body-viewer">
    <n-button 
      class="copy-btn" 
      size="tiny" 
      @click="copyCurrentFormat"
      circle
      quaternary
    >
      <template #icon>
        <n-icon :component="CopyOutline" />
      </template>
    </n-button>
    
    <n-tabs type="card" size="small" v-model:value="activeFormat" class="body-tabs">
      <n-tab-pane name="text" tab="Text">
        <pre class="body-content">{{ formatBodyAsText(body) }}</pre>
      </n-tab-pane>
      
      <n-tab-pane name="json" tab="JSON">
        <div class="json-content" v-html="formatBodyAsJsonHighlighted(body)"></div>
      </n-tab-pane>
      
      <n-tab-pane name="hex" tab="Hex">
        <pre class="body-content">{{ formatBodyAsHex(body) }}</pre>
      </n-tab-pane>
      
      <n-tab-pane name="xml" tab="XML">
        <pre class="body-content">{{ formatBodyAsXml(body) }}</pre>
      </n-tab-pane>
      
      <n-tab-pane name="javascript" tab="JavaScript">
        <pre class="body-content">{{ formatBodyAsJavaScript(body) }}</pre>
      </n-tab-pane>
    </n-tabs>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { useMessage } from 'naive-ui';
import CopyOutline from '@vicons/ionicons5/Copy';
import type { BodyFormat } from '../types/index';
import { copyToClipboard } from '../utils/clipboard';

interface Props {
  body: string;
  headers?: Record<string, string>;
}

const props = defineProps<Props>();
const message = useMessage();

const activeFormat = ref<BodyFormat>('text');

// 计算属性：处理body内容
const processedBody = computed(() => {
  // 后端已经处理了解压，直接返回内容
  return props.body || '';
});

// 复制当前格式的内容
async function copyCurrentFormat() {
  let content = '';
  
  switch (activeFormat.value) {
    case 'text':
      content = formatBodyAsText(props.body);
      break;
    case 'json':
      content = formatBodyAsJson(props.body);
      break;
    case 'hex':
      content = formatBodyAsHex(props.body);
      break;
    case 'xml':
      content = formatBodyAsXml(props.body);
      break;
    case 'javascript':
      content = formatBodyAsJavaScript(props.body);
      break;
  }
  
  const success = await copyToClipboard(content);
  if (success) {
    message.success(`${activeFormat.value.toUpperCase()} 格式内容已复制到剪贴板`);
  } else {
    message.error('复制失败');
  }
}

// Body 格式化函数
const formatBodyAsText = (body: string) => {
  return processedBody.value;
};

const formatBodyAsJson = (body: string) => {
  try {
    const content = processedBody.value;
    const parsed = JSON.parse(content);
    return JSON.stringify(parsed, null, 2);
  } catch (error) {
    return processedBody.value; // 如果不是有效的JSON，返回处理后的内容
  }
};

const formatBodyAsHex = (body: string) => {
  return processedBody.value
    .split('')
    .map((char: string) => char.charCodeAt(0).toString(16).padStart(2, '0'))
    .join(' ')
    .toUpperCase();
};

const formatBodyAsXml = (body: string) => {
  try {
    const content = processedBody.value;
    // 简单的XML格式化
    const formatted = content
      .replace(/></g, '>\n<')
      .replace(/^\s*\n/gm, '');
    return formatted;
  } catch (error) {
    return processedBody.value;
  }
};

const formatBodyAsJavaScript = (body: string) => {
  try {
    const content = processedBody.value;
    // 尝试将JSON转换为JavaScript对象格式
    const parsed = JSON.parse(content);
    return `const data = ${JSON.stringify(parsed, null, 2)};`;
  } catch (error) {
    // 如果不是JSON，就作为普通JavaScript代码处理
    return processedBody.value;
  }
};

// JSON 语法高亮函数
const formatBodyAsJsonHighlighted = (body: string) => {
  try {
    const content = processedBody.value;
    const parsed = JSON.parse(content);
    const formatted = JSON.stringify(parsed, null, 2);
    return highlightJson(formatted);
  } catch (error) {
    // 如果不是有效的JSON，返回处理后的内容
    return `<pre class="body-content">${escapeHtml(processedBody.value)}</pre>`;
  }
};

// 简单的 JSON 语法高亮
const highlightJson = (json: string) => {
  // 转义 HTML 字符
  const escaped = escapeHtml(json);
  
  return `<pre class="json-highlighted">${escaped
    // 键名高亮（深蓝色） - 先处理键名
    .replace(/^(\s*)("(?:[^"\\]|\\.)*")(\s*:\s*)/gm, '$1<span class="json-key">$2</span>$3')
    // 字符串值高亮（浅橙色）
    .replace(/:\s*("(?:[^"\\]|\\.)*")/g, ': <span class="json-string">$1</span>')
    // 数组中的字符串高亮
    .replace(/\[\s*("(?:[^"\\]|\\.)*")/g, '[<span class="json-string">$1</span>')
    .replace(/,\s*("(?:[^"\\]|\\.)*")/g, ', <span class="json-string">$1</span>')
    // 数字高亮（浅绿色）
    .replace(/:\s*(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/g, ': <span class="json-number">$1</span>')
    .replace(/\[\s*(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/g, '[<span class="json-number">$1</span>')
    .replace(/,\s*(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/g, ', <span class="json-number">$1</span>')
    // 布尔值高亮（蓝色）
    .replace(/:\s*(true|false)/g, ': <span class="json-boolean">$1</span>')
    .replace(/\[\s*(true|false)/g, '[<span class="json-boolean">$1</span>')
    .replace(/,\s*(true|false)/g, ', <span class="json-boolean">$1</span>')
    // null 高亮（蓝色）
    .replace(/:\s*(null)/g, ': <span class="json-null">$1</span>')
    .replace(/\[\s*(null)/g, '[<span class="json-null">$1</span>')
    .replace(/,\s*(null)/g, ', <span class="json-null">$1</span>')
    // 大括号和中括号高亮（金色）
    .replace(/([{}[\],])/g, '<span class="json-bracket">$1</span>')
  }</pre>`;
};

// 转义 HTML 字符
const escapeHtml = (text: string) => {
  const div = document.createElement('div');
  div.textContent = text;
  return div.innerHTML;
};
</script>

<style scoped lang="less">
.body-viewer {
  height: 100%;
  position: relative;
  
  .copy-btn {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 10;
    background: var(--bg-color);
    border: 1px solid var(--border-color);
    opacity: 0.7;
    transition: all 0.2s ease;
    
    &:hover {
      opacity: 1;
      background: var(--primary-color-suppl);
      border-color: var(--primary-color);
    }
  }
  
  .body-tabs {
    height: 100%;
    overflow: hidden;
  }
  
  .body-content {
    margin: 0;
    padding: 12px;
    background: var(--bg-color);
    border-radius: 4px;
    border: 1px solid var(--border-color);
    white-space: pre-wrap;
    word-break: break-all;
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size: 12px;
    line-height: 1.4;
    color: var(--text-color);
    height: 100%;
    overflow-y: auto;
    box-sizing: border-box;
  }
  
  .json-content {
    height: 100%;
    overflow-y: auto;
  }
  
  .json-highlighted {
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size: 12px;
    line-height: 1.5;
    background: var(--json-bg, #1e1e1e);
    color: var(--json-text, #d4d4d4);
    padding: 12px;
    border-radius: 6px;
    margin: 0;
    overflow-x: auto;
    border: 1px solid var(--json-border, #333);
  }
  
  /* JSON 语法高亮颜色 - 暗色主题 */
  :deep(.json-string) {
    color: var(--json-string, #ce9178);
  }
  
  :deep(.json-number) {
    color: var(--json-number, #b5cea8);
  }
  
  :deep(.json-boolean) {
    color: var(--json-boolean, #569cd6);
  }
  
  :deep(.json-null) {
    color: var(--json-null, #569cd6);
  }
  
  :deep(.json-key) {
    color: var(--json-key, #9cdcfe);
  }
  
  :deep(.json-bracket) {
    color: var(--json-bracket, #ffd700);
    font-weight: bold;
  }
}

// Body 格式切换的 card tabs 样式
:deep(.n-tabs--card-type) {
  .n-tabs-nav {
    padding: 4px;
    background: var(--bg-tertiary);
    border-radius: 4px;
  }
  
  .n-tabs-tab {
    font-size: 11px;
    padding: 4px 8px;
    margin: 0 2px;
    border-radius: 3px;
    color: var(--text-color);
    
    &.n-tabs-tab--active {
      background: var(--primary-color);
      color: white;
    }
  }
}

:deep(.n-tabs) {
  height: 100%;
  display: flex;
  flex-direction: column;
  
  .n-tabs-nav {
    background: var(--bg-color);
    border-bottom: 1px solid var(--border-color);
    flex-shrink: 0;
  }
}

:deep(.n-tabs-content) {
  flex: 1;
  overflow: hidden;
  background: var(--bg-color);
  display: flex;
  flex-direction: column;
}

:deep(.n-tab-pane) {
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
</style> 